package io.renren.service.impl;

import io.renren.common.exception.RRException;
import io.renren.common.utils.ConfigConstant;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.DecimalUtils;
import io.renren.common.utils.HttpClientUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.ProjectConstant;
import io.renren.common.utils.Query;
import io.renren.common.validator.Assert;
import io.renren.dao.BalanceTopupDao;
import io.renren.entity.BalanceTopupEntity;
import io.renren.entity.MemberEntity;
import io.renren.form.CallbackForm;
import io.renren.service.BalanceTopupService;
import io.renren.service.MemberService;
import io.renren.service.SysConfigService;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

@Service("balanceTopupService")
public class BalanceTopupServiceImpl extends ServiceImpl<BalanceTopupDao, BalanceTopupEntity> implements BalanceTopupService {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	SysConfigService sysConfigService;

	@Autowired
	MemberService memberService;

	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		Integer type = (Integer) params.get("type");
		Long memberId = (Long) params.get("memberId");
		Page<BalanceTopupEntity> page = this.selectPage(new Query<BalanceTopupEntity>(params).getPage(), new EntityWrapper<BalanceTopupEntity>().eq("member_id", memberId).eq("type", type).orderBy("create_time", false));
		return new PageUtils(page);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional(rollbackFor = Exception.class)
	public void submitDeposit(Long userId, Double amount, Integer paymentType) {
		double min = sysConfigService.getValueD(ConfigConstant.LOWEST_DEPOSIT_AMOUNT);
		Assert.isTrue(amount >= min, "最低充值金额为:" + min + "元");
		double max = sysConfigService.getValueD(ConfigConstant.HIGHEST_DEPOSIT_AMOUNT);
		Assert.isTrue(amount <= max, "最高充值金额为:" + max + "元");

		BalanceTopupEntity entity = new BalanceTopupEntity();
		// 支付交易类型
		switch (paymentType) {
		case ProjectConstant.PAYMENT_TYPE_ALIPAY:
			Assert.isTrue(sysConfigService.getValueD(ConfigConstant.ENABLE_ALIAPY_PAYMENT) == ProjectConstant.COMMON_YES, "当前支付通道不可用");
			entity.setDescription("支付宝充值");
			entity.setPayWay("alipay");
			break;
		case ProjectConstant.PAYMENT_TYPE_WECHAT:
			Assert.isTrue(sysConfigService.getValueD(ConfigConstant.ENABLE_WECHAT_PAYMENT) == ProjectConstant.COMMON_YES, "当前支付通道不可用");
			entity.setDescription("微信充值");
			entity.setPayWay("wechat");
			break;
		case ProjectConstant.PAYMENT_TYPE_UNIONPAY:
			Assert.isTrue(sysConfigService.getValueD(ConfigConstant.ENABLE_UNIONPAY_PAYMENT) == ProjectConstant.COMMON_YES, "当前支付通道不可用");
			entity.setDescription("银行卡充值");
			entity.setPayWay("unionpay");
			break;
		default:
			throw new RRException("不支持的支付方式");
		}

		Date now = new Date();

		entity.setMemberId(userId);
		entity.setMobile(memberService.selectById(userId).getMobile());
		entity.setAmount(amount);
		entity.setStatus(ProjectConstant.AUTH_STATUS_PENDING);
		entity.setType(ProjectConstant.ORDER_TYPE_DEPOSIT);
		entity.setCreateTime(now);
		entity.setOrderNo(DateUtils.format(now, "yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(6));
		this.insert(entity);

		// 调用第三方支付
//		String parentKey = sysConfigService.getValue(ConfigConstant.THIRD_PAYMENT_KEY);
//		String parentId = sysConfigService.getValue(ConfigConstant.THIRD_PAYMENT_ID);
//		String ts = DateUtils.format(now, DateUtils.DATE_TIME_PATTERN);
//		String noticeUrl = sysConfigService.getValue(ConfigConstant.WEB_PAGE) + "/api/topup/callbackDeposit";
//		String extra = "";
//		String sign = DigestUtils.md5Hex(parentId + amount + entity.getOrderNo() + parentKey);
//		String result = HttpClientUtils.sendHttpPost(sysConfigService.getValue(ConfigConstant.THIRD_PAYMENT_URL), "parent_id=" + parentId + "&amount=" + amount + "&ts=" + ts + "&notice_url=" + noticeUrl + "&extra=" + extra + "&order_number=" + entity.getOrderNo() + "&sign="
//				+ sign);
//		logger.info("第三方支付同步返回信息:" + result);
//		Assert.hasText(result, "充值失败");
//		Map<String, Object> map = JSON.parseObject(result, Map.class);
//		Assert.isTrue((Integer) map.get("errno") == 0, "充值失败");
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void callbackDeposit(CallbackForm form) {

	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void submitWithdraw(Long userId, Double amount, Integer paymentType) {
		double min = sysConfigService.getValueD(ConfigConstant.LOWEST_WITHDRAW_AMOUNT);
		Assert.isTrue(amount >= min, "最低提现金额为:" + min + "元");

		MemberEntity member = memberService.selectById(userId);
		Assert.isTrue(amount <= member.getBalance(), "余额不足");
		Assert.isTrue(member.getWithdrawAmountLimit() == 0, "您还差" + member.getWithdrawAmountLimit() + "元流水可提现");

		Date now = new Date();

		BalanceTopupEntity entity = new BalanceTopupEntity();
		// 支付交易类型
		switch (paymentType) {
		case ProjectConstant.PAYMENT_TYPE_ALIPAY:
			Assert.isTrue(sysConfigService.getValueD(ConfigConstant.ENABLE_ALIAPY_WITHDRAW) == ProjectConstant.COMMON_YES, "当前提现通道不可用");
			Assert.hasText(member.getAlipay(), "请先绑定支付宝");
			entity.setDescription("支付宝提现");
			entity.setPayWay("alipay");
			break;
		case ProjectConstant.PAYMENT_TYPE_WECHAT:
			Assert.isTrue(sysConfigService.getValueD(ConfigConstant.ENABLE_WECHAT_WITHDRAW) == ProjectConstant.COMMON_YES, "当前提现通道不可用");
			Assert.hasText(member.getWechat(), "请先绑定微信支付");
			entity.setDescription("微信提现");
			entity.setPayWay("wechat");
			break;
		case ProjectConstant.PAYMENT_TYPE_UNIONPAY:
			Assert.isTrue(sysConfigService.getValueD(ConfigConstant.ENABLE_UNIONPAY_WITHDRAW) == ProjectConstant.COMMON_YES, "当前提现通道不可用");
			Assert.hasText(member.getBankCardNumber(), "请先绑定银行卡");
			entity.setDescription("银行卡提现");
			entity.setPayWay("unionpay");
			break;
		default:
			throw new RRException("不支持的提现方式");
		}

		entity.setMemberId(userId);
		entity.setMobile(member.getMobile());
		entity.setFee(DecimalUtils.mul(amount, sysConfigService.getValueD(ConfigConstant.WITHDRAW_FEE)));
		entity.setAmount(new BigDecimal(amount.toString()).subtract(new BigDecimal(entity.getFee().toString())).setScale(2, RoundingMode.DOWN).negate().doubleValue());
		entity.setStatus(ProjectConstant.AUTH_STATUS_PENDING);
		entity.setType(ProjectConstant.ORDER_TYPE_WITHDRAW);
		entity.setCreateTime(now);
		entity.setOrderNo(DateUtils.format(now, "yyyyMMddHHmmss") + RandomStringUtils.randomNumeric(6));
		this.insert(entity);

		// 扣减余额
		member.setBalance(DecimalUtils.sub(member.getBalance(), amount));
		member.setBlockedBalance(DecimalUtils.add(member.getBlockedBalance(), amount));
		Assert.isTrue(memberService.updateById(member), "提现失败");
	}

	@Override
	public void callbackWithdraw(CallbackForm form) {

	}
}
